
 
import time 
 
from backend.backend import Backend
from workflow.task import Task
from workflow.result import Result 
from workflow.flowData import Status

class PizzatimeBackend(Backend):
    '''
    The PizzatimeBackend "class" is a collection of the "methods" (functions) that do the actual
    wiring together of the steps in the coffee bar process.
    
    A back end will always include the methods __init__ and wire and will also include a method
    to handle each event that occurs in the process.  For Lab 5 we have set up the two additional
    methods you need:  pizza_order_taken and pizza_prepared.
    
    See instruction documentation to see what you need to do.
    '''
   
    def __init__(self): 
        # Specify the workflow name:       
        Backend.__init__(self,"pizzatime", dashboard=True)

    def wire(self):
        '''
        The wire method is where we tell MWP which tasks to keep track of.
        To register a task, you will need to add a line of code that looks
        like this:
        self.register_result_listener("RoleName", "TaskName", self.method_name)
        Where: RoleName is the person who did the task
               TaskName is the name of the task they did
               self.method_name refers to a method in this class which should respond to
                                the task being completed.
        '''
        # !!! add a line of code here to register the step where a pizza order is taken.
        self.register_result_listener("server", "takeorder", self.pizza_order_entered)
        # !!! add a line of code here to register the step where a pizza is prepared.
        self.register_result_listener("chef", "cook", self.pizza_order_cooked)
        self.register_result_listener("chef", "ready", self.pizza_order_ready)
        #self.register_result_listener("server_p", "readyfromchef_p", self.pizza_order_served)
        self.register_result_listener("server", "serve", self.pizza_order_served)
        

    def pizza_order_entered(self, results):
        '''
        This method (i.e. function) gets called to update data and schedule any tasks
        necessary after a pizza order is taken.  Specifically, this function
        will set the status to "complete" on the "take pizza order" task
        and assigns the preparation of this pizza to the chef_p.
        '''
        for result in results:  # repeat the following actions for each result
            # !!! Fix the line below...
            task = Task.construct_from_result(result, "chef", "cook") 
            self.workflow.add(task) # add the new task to the workflow
            self.workflow.update_status(result, Status.COMPLETE)

    def pizza_order_cooked(self, results):
        '''
        This method is called after the chef_p has prepared the pizza.  
        In our very simple workflow this is the last step in the process, 
        which means that this method has a very simple job:  it just needs to mark 
        the status of the chef_p's task (stored in the results variable) as Complete.  
        '''
        #!!! Replace this pass, with appropriate code (using the pizza_order_taken) method
        #as insipiration...
        for result in results:  # repeat the following actions for each result
            # !!! Fix the line below... 
            task = Task.construct_from_result(result, "chef", "ready") 
            task.set_field("StartTime", time.time())
            self.workflow.add(task)
            self.workflow.update_status(result, Status.COMPLETE)
            
    def pizza_order_ready(self, results):
        '''
        This method is called after the chef has prepared the pizza.  
        In our very simple workflow this is the last step in the process, 
        which means that this method has a very simple job:  it just needs to mark 
        the status of the chef's task (stored in the results variable) as Complete.  
        '''
        #!!! Replace this pass, with appropriate code (using the pizza_order_taken) method
        #as insipiration...
        for result in results:  # repeat the following actions for each result
            start_time = result.get_float_field("StartTime")
            duration = time.time() - start_time
            
            task = Task.construct_from_result(result, "server", "serve") 
            task.set_field("CookingTime", duration)
            self.workflow.add(task) # add the new task to the workflow
            self.workflow.update_status(result, Status.COMPLETE)
            
    def pizza_order_served(self, results):
        '''
        This method is called after the chef has prepared the pizza.  
        In our very simple workflow this is the last step in the process, 
        which means that this method has a very simple job:  it just needs to mark 
        the status of the chef's task (stored in the results variable) as Complete.  
        '''
        #!!! Replace this pass, with appropriate code (using the pizza_order_taken) method
        #as insipiration...
        for result in results:  # repeat the following actions for each result
            # !!! Fix the line below... 
            self.workflow.update_status(result, Status.COMPLETE)

'''
Finally, this last bit of code is fine as it is and you do not need to change it.
It initialize the backend by running the __init__ method
of the PizzatimeBackend class (above), among other things.
'''
if __name__ == '__main__':
    backend = PizzatimeBackend()